`include "chunjun_define.sv" 
`include "chunjun_lib_define.sv" 
 
//================================================================================================
// File Name   : vtcu_bank_router_scatter.sv
// Create Time : Fri Jan  3 18:33:56 2025
// Description : Split a wide request into BANK_N small requests. New requests and VTCM bank are in one2one correspondence.
//               And generate a destnation-onehot-array for read result reshuffle.
//================================================================================================
 
module vtcu_bank_router_scatter #(parameter BANK_N      = `CHUNJUN_VTCM_BANK_N      ,
                                            BANK_DATA_W = `CHUNJUN_VTCM_RAM_DATA_W  , // do not modify this param at this version
                                            DATA_W      = 64                        , 
                                            MODE        = 2'b00                     , // do not modify this param at this version
                                            N           = DATA_W/BANK_DATA_W
) (
input   logic                                                   origin_vld          ,
input   logic                                                   origin_wr           ,
input   logic [20-1:0]                         origin_addr         ,
input   logic [DATA_W-1:0]                                      origin_wdata        ,
input   logic [DATA_W/8-1:0]                                    origin_wstrb        ,
 
output  logic [BANK_N-1:0]                                      req_vld             ,
output  logic [BANK_N-1:0]                                      req_wr              ,
output  logic [BANK_N-1:0][20-1:0]             req_addr            ,
output  logic [BANK_N-1:0][BANK_DATA_W-1:0]                     req_wdata           ,
output  logic [BANK_N-1:0][BANK_DATA_W/8-1:0]                   req_wstrb           ,
output  logic [BANK_N-1:0][N-1:0]                               req_rdata_dest_oh
); 

genvar i,j;
integer x;
localparam ALIGN_W      = $clog2(BANK_DATA_W/8) ; // 2
localparam BANK_W       = $clog2(BANK_N)        ; // 1
localparam SPLIT_LSB    = BANK_W + ALIGN_W      ; // 3 = 1+2
 
 
logic [N-1:0][BANK_W-1:0] origin_addr_bank_sel;
 
logic [N-1:0][20-1:0]              req_addr_tmp;
logic [N-1:0][BANK_DATA_W-1:0]                      req_wdata_tmp;
logic [N-1:0][BANK_DATA_W/8-1:0]                    req_wstrb_tmp;           
logic [N-1:0][N-1:0]                                req_rdata_dest_oh_tmp;


generate
if(MODE==2'b00)begin : GEN_SCATTER_MODE0
    for(i=0;i<N;i=i+1)begin: GEN_SPLIT_ORIGIN_REQ
        assign req_wdata_tmp[i]             = origin_wdata[BANK_DATA_W*i +: BANK_DATA_W];
        assign req_wstrb_tmp[i]             = origin_wstrb[BANK_DATA_W/8*i +: BANK_DATA_W/8];
        for(j=0;j<N;j=j+1) begin: GEN_SPLIT_ORIGIN_REQ_DEST_OH_TMP
            assign req_rdata_dest_oh_tmp[i][j]  = i==j;
        end

        assign origin_addr_bank_sel[i]      = origin_addr[ALIGN_W +: BANK_W] + i;
        assign req_addr_tmp[i]              = {origin_addr[SPLIT_LSB +: (20-SPLIT_LSB)], origin_addr_bank_sel[i], origin_addr[0 +: ALIGN_W]} ;
    end
    for(i=0;i<BANK_N;i=i+1) begin: GEN_REQ_ROUTE
        assign req_wr[i] = origin_wr;
        always @(*) begin
            req_vld[i]              = 'h0;
            req_addr[i]             = 'h0; 
            req_wdata[i]            = 'h0;
            req_wstrb[i]            = 'h0;
            req_rdata_dest_oh[i]    = 'h0;
            for(x=0;x<N;x=x+1) begin
                req_vld[i]              = req_vld[i]            | ((origin_addr_bank_sel[x] == i) && origin_vld);
                req_addr[i]             = req_addr[i]           | ({20{(origin_addr_bank_sel[x] == i)}} & req_addr_tmp[x]);
                req_wdata[i]            = req_wdata[i]          | ({BANK_DATA_W{(origin_addr_bank_sel[x] == i)}} & req_wdata_tmp[x]);
                req_wstrb[i]            = req_wstrb[i]          | ({(BANK_DATA_W/8){(origin_addr_bank_sel[x] == i)}} & req_wstrb_tmp[x]);
                req_rdata_dest_oh[i]    =req_rdata_dest_oh[i]   | ({N{(origin_addr_bank_sel[x] == i)}} & req_rdata_dest_oh_tmp[x]);
            end
        end
    end
 
end
else begin : GEN_SCATTER_MODEX
    assign req_vld              = 'h0;
    assign req_wr               = 'h0;
    assign req_addr             = 'h0;
    assign req_wdata            = 'h0;
    assign req_wstrb            = 'h0;
    assign req_rdata_dest_oh    = 'h0;
end
 
 
endgenerate







endmodule

`include "chunjun_undefine.sv" 
